package org.smart4j.framework.helper;

import org.smart4j.framework.annotation.Action;
import org.smart4j.framework.bean.Handler;
import org.smart4j.framework.bean.Request;
import org.smart4j.util.ArrayUtil;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 控制器助手类
 *
 * @author why-stark
 * @since 1.0.0
 */
public final class ControllerHelper {

    /**
     * 用于存放请求与处理器的映射关系 （简称 Action Map）
     */
    private static final Map<Request, Handler> ACTION_MAP = new HashMap<Request, Handler>();

    static {
        // 获取所有 Controller 类
        Set<Class<?>> controllerClassSet = ClassHelper.getControllerClassSet();
        // 遍历这些 Controller 类
        for (Class<?> controllerClass : controllerClassSet) {
            // 获取 Controller 类中定义的方法
            Method[] controllerMethods = controllerClass.getDeclaredMethods();
            if (ArrayUtil.isNotEmpty(controllerMethods)) {
                for (Method method : controllerMethods) {
                    if (method.isAnnotationPresent(Action.class)) {
                        // 从 Action 注解中获取 URL 映射规则
                        Action action = method.getAnnotation(Action.class);
                        String mapping = action.value();
                        // 验证 URL 映射规则
                        if (mapping.matches("\\w+:/\\w*")) {
                            String[] strArray = mapping.split(",");
                            if (ArrayUtil.isNotEmpty(strArray) && strArray.length == 2) {
                                // 获取请求方法与请求路径
                                String requestMethod = strArray[0];
                                String requestPath = strArray[1];
                                Request request = new Request(requestMethod, requestPath);
                                Handler handler = new Handler(controllerClass, method);
                                // 初始化 Action Map
                                ACTION_MAP.put(request, handler);
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 获取 Handler
     */
    public static Handler getHandler(String requestMethod, String requestPath) {
        Request request = new Request(requestMethod, requestPath);
        if (!ACTION_MAP.containsKey(request)) {
            throw new RuntimeException("can not get handler by request" + request);
        }
        return ACTION_MAP.get(request);
    }
}
